package com.honkentuber;

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.json.simple.JSONObject;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.repackaged.com.google.common.base.Preconditions;
import com.google.appengine.repackaged.com.google.common.collect.Maps;
import com.google.appengine.repackaged.com.google.common.collect.Sets;

public class MyUserCache {
  private final static Logger LOG =
      Logger.getLogger(MyUserCache.class.getName());

  private final Map<Key, MyUser> CACHE = Maps.newHashMap();

  private final Set<Key> TO_CACHE = Sets.newHashSet();

  public synchronized void add(MyUser user) {
    if (user != null) {
      LOG.config("adding " + user.getKey() + " cache");
      CACHE.put(user.getKey(), user);
      TO_CACHE.remove(user.getKey());
    }
  }

  public synchronized void add(Key key) {
    if (key != null && !CACHE.containsKey(key)) {
      TO_CACHE.add(key);
    }
  }

  public synchronized void loadCache(Database db) {
    if (!TO_CACHE.isEmpty()) {
      LOG.config("adding " + TO_CACHE.size() + " entries to cache");
      // TODO(ptucker): perform a single search
      for (Key key : TO_CACHE) {
        MyUser user = db.fetchUser(key, true /* noCache */);
        Preconditions.checkNotNull(user);
        CACHE.put(key, user);
      }
      TO_CACHE.clear();
    }
  }

  public synchronized Map<Key, MyUser> getUsers() {
    return Collections.unmodifiableMap(CACHE);
  }

  public synchronized void delete(Key key) {
    if (key != null) {
      LOG.config("removing " + key + " from cache");
      CACHE.remove(key);
      TO_CACHE.remove(key);
    }
  }

  @SuppressWarnings("unchecked")
  public synchronized JSONObject toJson() {
    JSONObject jsonUserCache = new JSONObject();
    for (MyUser user : getUsers().values()) {
      jsonUserCache.put(KeyFactory.keyToString(user.getKey()), user.toJson());
    }
    return jsonUserCache;
  }
}
